package com.sky.aspect;


import com.sky.anno.TableInjectAnnotation;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
public class TableInjectAspect {


    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.anno.TableInjectAnnotation)")
    public void pt() {
    }

    @Before("pt()")
    public void before(JoinPoint joinPoint) {
        System.out.println("=======执行了TableInjectAspect的before方法========");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取当前执行的方法
        Method method = signature.getMethod();
        // 获取方法上的注解
        TableInjectAnnotation tableInjectAnnotation = method.getAnnotation(TableInjectAnnotation.class);
        // 获取注解中的内容进行swtich
        OperationType operationType = tableInjectAnnotation.value();
        // 获取方法的参数对象
        Object arg = joinPoint.getArgs()[0];
        // 提高代码的健壮性
        if (arg == null || joinPoint.getArgs().length == 0 || joinPoint.getArgs().length > 1) {
            return;
        }
        // 获取当前参数对象中的方法，和这个参数对象方法中的参数
        try {
            Method createTimeMethod = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method updateTimeMethod = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method createUserMethod = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method updateUserMethod = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            LocalDateTime now = LocalDateTime.now();
            Long currentId = BaseContext.getCurrentId();
            switch (operationType) {
                case INSERT:
                    createTimeMethod.invoke(arg, now);
                    updateTimeMethod.invoke(arg, now);
                    createUserMethod.invoke(arg, currentId);
                    updateUserMethod.invoke(arg, currentId);
                    System.out.println("执行添加");
                    break;
                case UPDATE:
                    updateTimeMethod.invoke(arg, now);
                    updateUserMethod.invoke(arg, currentId);
                    System.out.println("执行修改");
                    break;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
